﻿using System;
using System.Xml;
using Stonecode.Solar.ParticleEngine.Emitters;
using System.Collections.Generic;
using System.Text;
using Stonecode.Solar.ParticleEngine;
using Stonecode.Solar.ParticleEngine.Collections;
using System.Xml.XPath;
using System.Data;
using Microsoft.Xna.Framework.Graphics;

namespace Stonecode.Solar.ParticleEffectEditor.Serialization
{
    using GdiColor = System.Drawing.Color;
    using XnaColor = Microsoft.Xna.Framework.Color;
    using Microsoft.Xna.Framework;

    static class FileHandler
    {
        public static void WriteFile(string file, EmitterCollection eColl)
        {
            XmlDocument doc = new XmlDocument();
            XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "utf-8", null);
            XmlElement root = doc.CreateElement("XNAContent");
            doc.InsertBefore(declaration, doc.DocumentElement);
            doc.AppendChild(root);
            XmlElement collectionRoot = doc.CreateElement("EmitterCollection");
            root.AppendChild(collectionRoot);

            foreach (Emitter e in eColl)
            {
                XmlElement emitterRoot = doc.CreateElement("Emitter");
                collectionRoot.AppendChild(emitterRoot);
                
                // name of the emitter
                XmlElement name = doc.CreateElement("Name");
                name.InnerText = e.EmitterName;
                emitterRoot.AppendChild(name);

                XmlElement emitterTypeSettings = doc.CreateElement("EmitterTypeSettings");
                emitterRoot.AppendChild(emitterTypeSettings);

                #region EmitterType Specific
                // Write the EmitterType Specific stuff (i.e Circle, Line, etc.)
                switch (e.EmitterType)
                {
                    case EmitterType.Circle:
                        {
                            CircleEmitterTypeSettings ts = ((CircleEmitter)e).EmitterTypeSettings;
                            XmlElement val = doc.CreateElement("EmitterType");
                            val.InnerText = e.EmitterType.ToString();
                            emitterTypeSettings.AppendChild(val);

                            val = doc.CreateElement("Radius");
                            val.InnerText = ts.Radius.ToString();
                            emitterTypeSettings.AppendChild(val);

                            val = doc.CreateElement("RadiateOutward");
                            val.InnerText = ts.RadiateOutward.ToString();
                            emitterTypeSettings.AppendChild(val);

                            val = doc.CreateElement("StartAngle");
                            val.InnerText = ts.StartAngle.ToString();
                            emitterTypeSettings.AppendChild(val);

                            val = doc.CreateElement("EndAngle");
                            val.InnerText = ts.EndAngle.ToString();
                            emitterTypeSettings.AppendChild(val);
                            break;
                        }
                    case EmitterType.Line:
                        {
                            LineEmitterTypeSettings ts = ((LineEmitter)e).EmitterTypeSettings;
                            XmlElement val = doc.CreateElement("EmitterType");
                            val.InnerText = e.EmitterType.ToString();
                            emitterTypeSettings.AppendChild(val);
                            // Line Length
                            val = doc.CreateElement("LineLength");
                            val.InnerText = ts.LineLength.ToString();
                            emitterTypeSettings.AppendChild(val);
                            // Rotation
                            val = doc.CreateElement("Rotation");
                            val.InnerText = ts.Rotation.ToString();
                            emitterTypeSettings.AppendChild(val);
                            // Perpendicular Velocity
                            val = doc.CreateElement("PerpendicularVelocity");
                            val.InnerText = ts.PerpendicularVelocity.ToString();
                            emitterTypeSettings.AppendChild(val);
                            break;
                        }
                    case EmitterType.Point:
                        {
                            PointEmitterTypeSettings ts = ((PointEmitter)e).EmitterTypeSettings;
                            XmlElement val = doc.CreateElement("EmitterType");
                            val.InnerText = e.EmitterType.ToString();
                            emitterTypeSettings.AppendChild(val);
                            // ElipticalVelocity
                            val = doc.CreateElement("ElipticalVelocity");
                            val.InnerText = ts.EllipticalVelocity.ToString();
                            emitterTypeSettings.AppendChild(val);
                            break;
                        }
                    case EmitterType.Rectangle:
                        {
                            RectangleEmitterTypeSettings ts = ((RectangleEmitter)e).EmitterTypeSettings;
                            XmlElement val = doc.CreateElement("EmitterType");
                            val.InnerText = e.EmitterType.ToString();
                            emitterTypeSettings.AppendChild(val);

                            val = doc.CreateElement("Rectangle");
                            val.Attributes.Append(doc.CreateAttribute("X"));
                            val.Attributes.Append(doc.CreateAttribute("Y"));
                            val.Attributes.Append(doc.CreateAttribute("Width"));
                            val.Attributes.Append(doc.CreateAttribute("Height"));
                            val.Attributes["X"].Value = ts.Rectangle.X.ToString();
                            val.Attributes["Y"].Value = ts.Rectangle.Y.ToString();
                            val.Attributes["Width"].Value = ts.Rectangle.Width.ToString();
                            val.Attributes["Height"].Value = ts.Rectangle.Height.ToString();
                            emitterTypeSettings.AppendChild(val);

                            // Rotation
                            val = doc.CreateElement("Rotation");
                            val.InnerText = ts.Rotation.ToString();
                            emitterTypeSettings.AppendChild(val);

                            // Create On Edge
                            val = doc.CreateElement("CreateOnEdge");
                            val.InnerText = ts.CreateOnEdge.ToString();
                            emitterTypeSettings.AppendChild(val);

                            // Create On Edge
                            val = doc.CreateElement("RotateVelocity");
                            val.InnerText = ts.RotateVelocity.ToString();
                            emitterTypeSettings.AppendChild(val);

                            break;
                        }
                }
                #endregion

                #region EmitterSettings
                XmlElement myClass;
                XmlElement myVal;

                // MaxParticles (Budget)
                myVal = doc.CreateElement("TextureName");
                myVal.InnerText = e.ParticleSystem.Settings.TextureName.ToString();
                emitterRoot.AppendChild(myVal);

                // MaxParticles (Budget)
                myVal = doc.CreateElement("MaxParticles");
                myVal.InnerText = e.ParticleSystem.Settings.MaxParticles.ToString();
                emitterRoot.AppendChild(myVal);
                // ParticlesPerSecond
                myVal = doc.CreateElement("ParticlesPerSecond");
                myVal.InnerText = e.ParticleSystem.Settings.ParticlesPerSecond.ToString();
                emitterRoot.AppendChild(myVal);
                // Duration
                myVal = doc.CreateElement("Duration");
                myVal.InnerText = e.ParticleSystem.Settings.Duration.ToString();
                emitterRoot.AppendChild(myVal);
                myVal = doc.CreateElement("DurationRandomness");
                myVal.InnerText = e.ParticleSystem.Settings.DurationRandomness.ToString();
                emitterRoot.AppendChild(myVal);
                // Enabled
                myVal = doc.CreateElement("Enabled");
                myVal.InnerText = e.ParticleSystem.Settings.Enabled.ToString();
                emitterRoot.AppendChild(myVal);

                // Position
                myClass = doc.CreateElement("Position");
                emitterRoot.AppendChild(myClass);

                myVal = doc.CreateElement("Offset");
                myVal.Attributes.Append(doc.CreateAttribute("X"));
                myVal.Attributes.Append(doc.CreateAttribute("Y"));
                myVal.Attributes.Append(doc.CreateAttribute("Z"));
                myVal.Attributes["X"].Value = e.ParticleSystem.Settings.Offset.X.ToString();
                myVal.Attributes["Y"].Value = e.ParticleSystem.Settings.Offset.Y.ToString();
                myVal.Attributes["Z"].Value = e.ParticleSystem.Settings.Offset.Z.ToString();
                myClass.AppendChild(myVal);

                // Velocity
                myClass = doc.CreateElement("Velocity");
                emitterRoot.AppendChild(myClass);

                myVal = doc.CreateElement("MinHorizontal");
                myVal.InnerText = e.ParticleSystem.Settings.MinHorizontalVelocity.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("MaxHorizontal");
                myVal.InnerText = e.ParticleSystem.Settings.MaxHorizontalVelocity.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("MinVertical");
                myVal.InnerText = e.ParticleSystem.Settings.MinVerticalVelocity.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("MaxVertical");
                myVal.InnerText = e.ParticleSystem.Settings.MaxVerticalVelocity.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("Sensitivity");
                myVal.InnerText = e.ParticleSystem.Settings.EmitterVelocitySensitivity.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("Falloff");
                myVal.InnerText = e.ParticleSystem.Settings.EndVelocity.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("Gravity");
                myVal.Attributes.Append(doc.CreateAttribute("X"));
                myVal.Attributes.Append(doc.CreateAttribute("Y"));
                myVal.Attributes.Append(doc.CreateAttribute("Z"));
                myVal.Attributes["X"].Value = e.ParticleSystem.Settings.Gravity.X.ToString();
                myVal.Attributes["Y"].Value = e.ParticleSystem.Settings.Gravity.Y.ToString();
                myVal.Attributes["Z"].Value = e.ParticleSystem.Settings.Gravity.Z.ToString();
                myClass.AppendChild(myVal);

                // Color
                myClass = doc.CreateElement("Color");
                emitterRoot.AppendChild(myClass);

                myVal = doc.CreateElement("MinColor");
                myVal.Attributes.Append(doc.CreateAttribute("A"));
                myVal.Attributes.Append(doc.CreateAttribute("R"));
                myVal.Attributes.Append(doc.CreateAttribute("G"));
                myVal.Attributes.Append(doc.CreateAttribute("B"));
                myVal.Attributes["A"].Value = e.ParticleSystem.Settings.MinColor.A.ToString();
                myVal.Attributes["R"].Value = e.ParticleSystem.Settings.MinColor.R.ToString();
                myVal.Attributes["G"].Value = e.ParticleSystem.Settings.MinColor.G.ToString();
                myVal.Attributes["B"].Value = e.ParticleSystem.Settings.MinColor.B.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("MaxColor");
                myVal.Attributes.Append(doc.CreateAttribute("A"));
                myVal.Attributes.Append(doc.CreateAttribute("R"));
                myVal.Attributes.Append(doc.CreateAttribute("G"));
                myVal.Attributes.Append(doc.CreateAttribute("B"));
                myVal.Attributes["A"].Value = e.ParticleSystem.Settings.MaxColor.A.ToString();
                myVal.Attributes["R"].Value = e.ParticleSystem.Settings.MaxColor.R.ToString();
                myVal.Attributes["G"].Value = e.ParticleSystem.Settings.MaxColor.G.ToString();
                myVal.Attributes["B"].Value = e.ParticleSystem.Settings.MaxColor.B.ToString();
                myClass.AppendChild(myVal);

                myClass = doc.CreateElement("Rotation");
                emitterRoot.AppendChild(myClass);

                myVal = doc.CreateElement("MinRotateSpeed");
                myVal.InnerText = e.ParticleSystem.Settings.MinRotateSpeed.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("MaxRotateSpeed");
                myVal.InnerText = e.ParticleSystem.Settings.MaxRotateSpeed.ToString();
                myClass.AppendChild(myVal);

                myClass = doc.CreateElement("Size");
                emitterRoot.AppendChild(myClass);

                myVal = doc.CreateElement("MinStartSize");
                myVal.InnerText = e.ParticleSystem.Settings.MinStartSize.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("MaxStartSize");
                myVal.InnerText = e.ParticleSystem.Settings.MaxStartSize.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("MinEndSize");
                myVal.InnerText = e.ParticleSystem.Settings.MinEndSize.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("MaxEndSize");
                myVal.InnerText = e.ParticleSystem.Settings.MaxEndSize.ToString();
                myClass.AppendChild(myVal);

                myClass = doc.CreateElement("Blend");
                emitterRoot.AppendChild(myClass);

                myVal = doc.CreateElement("AlphaSourceBlend");
                myVal.InnerText = e.ParticleSystem.Settings.AlphaSourceBlend.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("AlphaDestinationBlend");
                myVal.InnerText = e.ParticleSystem.Settings.AlphaDestinationBlend.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("AlphaBlendFunction");
                myVal.InnerText = e.ParticleSystem.Settings.AlphaBlendFunction.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("ColorBlendFunction");
                myVal.InnerText = e.ParticleSystem.Settings.ColorBlendFunction.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("ColorDestinationBlend");
                myVal.InnerText = e.ParticleSystem.Settings.ColorDestinationBlend.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("ColorSourceBlend");
                myVal.InnerText = e.ParticleSystem.Settings.ColorSourceBlend.ToString();
                myClass.AppendChild(myVal);

                myVal = doc.CreateElement("BlendFactor");
                //myVal.InnerText = e.ParticleSystem.Settings.BlendFactor.ToString();
                myVal.Attributes.Append(doc.CreateAttribute("A"));
                myVal.Attributes.Append(doc.CreateAttribute("R"));
                myVal.Attributes.Append(doc.CreateAttribute("G"));
                myVal.Attributes.Append(doc.CreateAttribute("B"));
                myVal.Attributes["A"].Value = e.ParticleSystem.Settings.BlendFactor.A.ToString();
                myVal.Attributes["R"].Value = e.ParticleSystem.Settings.BlendFactor.R.ToString();
                myVal.Attributes["G"].Value = e.ParticleSystem.Settings.BlendFactor.G.ToString();
                myVal.Attributes["B"].Value = e.ParticleSystem.Settings.BlendFactor.B.ToString();
                myClass.AppendChild(myVal);
                #endregion
            }

            try
            {
                doc.Save(file);
            }
            catch (System.IO.DirectoryNotFoundException ex) { }

        }

        #region Old Way
        //public static void WriteFile(string file, List<OutputSettings> settingsList)
        //{
        //    XmlDocument doc = new XmlDocument();
        //    XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "utf-8", null);
        //    XmlElement root = doc.CreateElement("XNAContent");
        //    doc.InsertBefore(declaration, doc.DocumentElement);
        //    doc.AppendChild(root);
        //    XmlElement collectionRoot = doc.CreateElement("EmitterCollection");
        //    root.AppendChild(collectionRoot);

        //    foreach (OutputSettings s in settingsList)
        //    {
        //        XmlElement emitterRoot = doc.CreateElement("Emitter");
        //        collectionRoot.AppendChild(emitterRoot);

        //        // name of the emitter
        //        XmlElement name = doc.CreateElement("Name");
        //        name.InnerText = s.EmitterName;
        //        emitterRoot.AppendChild(name);

        //        XmlElement emitterTypeSettings = doc.CreateElement("EmitterTypeSettings");
        //        emitterRoot.AppendChild(emitterTypeSettings);

        //        #region EmitterType Specific
        //        // Write the EmitterType Specific stuff (i.e Circle, Line, etc.)
        //        switch (s.EmitterType)
        //        {
        //            case EmitterType.Circle:
        //                {
        //                    CircleEmitterTypeSettings ts = (CircleEmitterTypeSettings)s.EmitterTypeSettings;
        //                    XmlElement val = doc.CreateElement("EmitterType");
        //                    val.InnerText = s.EmitterType.ToString();
        //                    emitterTypeSettings.AppendChild(val);

        //                    val = doc.CreateElement("Radius");
        //                    val.InnerText = ts.Radius.ToString();
        //                    emitterTypeSettings.AppendChild(val);

        //                    val = doc.CreateElement("RadiateOutward");
        //                    val.InnerText = ts.RadiateOutward.ToString();
        //                    emitterTypeSettings.AppendChild(val);

        //                    val = doc.CreateElement("StartAngle");
        //                    val.InnerText = ts.StartAngle.ToString();
        //                    emitterTypeSettings.AppendChild(val);

        //                    val = doc.CreateElement("EndAngle");
        //                    val.InnerText = ts.StartAngle.ToString();
        //                    emitterTypeSettings.AppendChild(val);
        //                    break;
        //                }
        //            case EmitterType.Line:
        //                {
        //                    LineEmitterTypeSettings ts = (LineEmitterTypeSettings)s.EmitterTypeSettings;
        //                    XmlElement val = doc.CreateElement("EmitterType");
        //                    val.InnerText = s.EmitterType.ToString();
        //                    emitterTypeSettings.AppendChild(val);
        //                    // Line Length
        //                    val = doc.CreateElement("LineLength");
        //                    val.InnerText = ts.LineLength.ToString();
        //                    emitterTypeSettings.AppendChild(val);
        //                    // Rotation
        //                    val = doc.CreateElement("Rotation");
        //                    val.InnerText = ts.Rotation.ToString();
        //                    emitterTypeSettings.AppendChild(val);
        //                    // Perpendicular Velocity
        //                    val = doc.CreateElement("PerpendicularVelocity");
        //                    val.InnerText = ts.PerpendicularVelocity.ToString();
        //                    emitterTypeSettings.AppendChild(val);
        //                    break;
        //                }
        //            case EmitterType.Point:
        //                {
        //                    XmlElement val = doc.CreateElement("EmitterType");
        //                    val.InnerText = s.EmitterType.ToString();
        //                    emitterTypeSettings.AppendChild(val);
                            
        //                    break;
        //                }
        //            case EmitterType.Rectangle:
        //                {
        //                    RectangleEmitterTypeSettings ts = (RectangleEmitterTypeSettings)s.EmitterTypeSettings;
        //                    XmlElement val = doc.CreateElement("EmitterType");
        //                    val.InnerText = s.EmitterType.ToString();
        //                    emitterTypeSettings.AppendChild(val);
                            
        //                    val = doc.CreateElement("Rectangle");
        //                    val.Attributes.Append(doc.CreateAttribute("X"));
        //                    val.Attributes.Append(doc.CreateAttribute("Y"));
        //                    val.Attributes.Append(doc.CreateAttribute("Width"));
        //                    val.Attributes.Append(doc.CreateAttribute("Height"));
        //                    val.Attributes["X"].Value = ts.Rectangle.X.ToString();
        //                    val.Attributes["Y"].Value = ts.Rectangle.Y.ToString();
        //                    val.Attributes["Width"].Value = ts.Rectangle.Width.ToString();
        //                    val.Attributes["Height"].Value = ts.Rectangle.Height.ToString();
        //                    emitterTypeSettings.AppendChild(val);

        //                    // Rotation
        //                    val = doc.CreateElement("Rotation");
        //                    val.InnerText = ts.Rotation.ToString();
        //                    emitterTypeSettings.AppendChild(val);

        //                    // Create On Edge
        //                    val = doc.CreateElement("CreateOnEdge");
        //                    val.InnerText = ts.CreateOnEdge.ToString();
        //                    emitterTypeSettings.AppendChild(val);

        //                    // Create On Edge
        //                    val = doc.CreateElement("RotateVelocity");
        //                    val.InnerText = ts.RotateVelocity.ToString();
        //                    emitterTypeSettings.AppendChild(val);

        //                    break;
        //                }
        //        }
        //        #endregion

        //        XmlElement myClass;
        //        XmlElement myVal;

        //        // MaxParticles (Budget)
        //        myVal = doc.CreateElement("TextureName");
        //        myVal.InnerText = s.TextureName.ToString();
        //        emitterRoot.AppendChild(myVal);

        //        // MaxParticles (Budget)
        //        myVal = doc.CreateElement("MaxParticles");
        //        myVal.InnerText = s.MaxParticles.ToString();
        //        emitterRoot.AppendChild(myVal);
        //        // ParticlesPerSecond
        //        myVal = doc.CreateElement("ParticlesPerSecond");
        //        myVal.InnerText = s.ParticlesPerSecond.ToString();
        //        emitterRoot.AppendChild(myVal);
        //        // Duration
        //        myVal = doc.CreateElement("Duration");
        //        myVal.InnerText = s.Duration.ToString();
        //        emitterRoot.AppendChild(myVal);
        //        myVal = doc.CreateElement("DurationRandomness");
        //        myVal.InnerText = s.DurationRandomness.ToString();
        //        emitterRoot.AppendChild(myVal);
        //        // Enabled
        //        myVal = doc.CreateElement("Enabled");
        //        myVal.InnerText = s.Enabled.ToString();
        //        emitterRoot.AppendChild(myVal);

        //        // Velocity
        //        myClass = doc.CreateElement("Velocity");
        //        emitterRoot.AppendChild(myClass);

        //        myVal = doc.CreateElement("MinHorizontal");
        //        myVal.InnerText = s.MinHorizontalVelocity.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("MaxHorizontal");
        //        myVal.InnerText = s.MaxHorizontalVelocity.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("MinVertical");
        //        myVal.InnerText = s.MinVerticalVelocity.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("MaxVertical");
        //        myVal.InnerText = s.MaxVerticalVelocity.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("Sensitivity");
        //        myVal.InnerText = s.EmitterVelocitySensitivity.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("Falloff");
        //        myVal.InnerText = s.EndVelocity.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("Gravity");
        //        myVal.Attributes.Append(doc.CreateAttribute("X"));
        //        myVal.Attributes.Append(doc.CreateAttribute("Y"));
        //        myVal.Attributes.Append(doc.CreateAttribute("Z"));
        //        myVal.Attributes["X"].Value = s.Gravity.X.ToString();
        //        myVal.Attributes["Y"].Value = s.Gravity.Y.ToString();
        //        myVal.Attributes["Z"].Value = s.Gravity.Z.ToString();
        //        myClass.AppendChild(myVal);

        //        // Color
        //        myClass = doc.CreateElement("Color");
        //        emitterRoot.AppendChild(myClass);

        //        myVal = doc.CreateElement("MinColor");
        //        myVal.Attributes.Append(doc.CreateAttribute("A"));
        //        myVal.Attributes.Append(doc.CreateAttribute("R"));
        //        myVal.Attributes.Append(doc.CreateAttribute("G"));
        //        myVal.Attributes.Append(doc.CreateAttribute("B"));
        //        myVal.Attributes["A"].Value = s.MinColor.A.ToString();
        //        myVal.Attributes["R"].Value = s.MinColor.R.ToString();
        //        myVal.Attributes["G"].Value = s.MinColor.G.ToString();
        //        myVal.Attributes["B"].Value = s.MinColor.B.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("MaxColor");
        //        myVal.Attributes.Append(doc.CreateAttribute("A"));
        //        myVal.Attributes.Append(doc.CreateAttribute("R"));
        //        myVal.Attributes.Append(doc.CreateAttribute("G"));
        //        myVal.Attributes.Append(doc.CreateAttribute("B"));
        //        myVal.Attributes["A"].Value = s.MaxColor.A.ToString();
        //        myVal.Attributes["R"].Value = s.MaxColor.R.ToString();
        //        myVal.Attributes["G"].Value = s.MaxColor.G.ToString();
        //        myVal.Attributes["B"].Value = s.MaxColor.B.ToString();
        //        myClass.AppendChild(myVal);

        //        myClass = doc.CreateElement("Rotation");
        //        emitterRoot.AppendChild(myClass);
                
        //        myVal = doc.CreateElement("MinRotateSpeed");
        //        myVal.InnerText = s.MinRotateSpeed.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("MaxRotateSpeed");
        //        myVal.InnerText = s.MaxRotateSpeed.ToString();
        //        myClass.AppendChild(myVal);

        //        myClass = doc.CreateElement("Size");
        //        emitterRoot.AppendChild(myClass);

        //        myVal = doc.CreateElement("MinStartSize");
        //        myVal.InnerText = s.MinStartSize.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("MaxStartSize");
        //        myVal.InnerText = s.MaxStartSize.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("MinEndSize");
        //        myVal.InnerText = s.MinEndSize.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("MaxEndSize");
        //        myVal.InnerText = s.MaxEndSize.ToString();
        //        myClass.AppendChild(myVal);

        //        myClass = doc.CreateElement("Blend");
        //        emitterRoot.AppendChild(myClass);

        //        myVal = doc.CreateElement("AlphaSourceBlend");
        //        myVal.InnerText = s.AlphaSourceBlend.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("AlphaDestinationBlend");
        //        myVal.InnerText = s.AlphaDestinationBlend.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("AlphaBlendFunction");
        //        myVal.InnerText = s.AlphaBlendFunction.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("BlendFactor");
        //        myVal.InnerText = s.BlendFactor.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("ColorBlendFunction");
        //        myVal.InnerText = s.ColorBlendFunction.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("ColorDestinationBlend");
        //        myVal.InnerText = s.ColorDestinationBlend.ToString();
        //        myClass.AppendChild(myVal);

        //        myVal = doc.CreateElement("ColorSourceBlend");
        //        myVal.InnerText = s.ColorSourceBlend.ToString();
        //        myClass.AppendChild(myVal);
        //    }

        //    try
        //    {
        //        doc.Save(file);
        //    }
        //    catch (System.IO.DirectoryNotFoundException ex) { }
        //}
        #endregion

        public static void ReadFile(string file, out List<OutputSettings> e)
        {
            e = new List<OutputSettings>();
            
            XmlDocument doc = new XmlDocument();
            doc.Load(file);
            XmlElement rootNode = doc.DocumentElement; // <XNAContent>
            XmlElement emitterList = (XmlElement)rootNode.ChildNodes[0]; // there should be only one list

            foreach (XmlNode node in emitterList.ChildNodes) // for each emitter in the list
            {
                OutputSettings settings = new OutputSettings();
                foreach (XmlNode node2 in node.ChildNodes)
                {
                    switch (node2.Name)
                    {
                        case "Name":
                            {
                                settings.EmitterName = node2.InnerText;
                                break;
                            }
                        case "TextureName":
                            {
                                settings.TextureName = node2.InnerText;
                                break;
                            }
                        case "EmitterTypeSettings":
                            {
                                settings.EmitterTypeSettings = ParseEmitterTypeSettings((XmlElement)node2);
                                settings.EmitterType = settings.EmitterTypeSettings.EmitterType;
                                break;
                            }
                        case "MaxParticles":
                            {
                                settings.MaxParticles = uint.Parse(node2.InnerText);
                                break;
                            }
                        case "ParticlesPerSecond":
                            {
                                settings.ParticlesPerSecond = float.Parse(node2.InnerText);
                                break;
                            }
                        case "Duration":
                            {
                                settings.Duration = TimeSpan.Parse(node2.InnerText);
                                break;
                            }
                        case "DurationRandomness":
                            {
                                settings.DurationRandomness = float.Parse(node2.InnerText);
                                break;
                            }
                        case "Enabled":
                            {
                                settings.Enabled = bool.Parse(node2.InnerText);
                                break;
                            }
                        case "Position":
                            {
                                settings.Offset = ParseVector3(node2["Offset"]);
                                break;
                            }
                        case "Velocity":
                            {
                                settings.MinHorizontalVelocity = float.Parse(node2["MinHorizontal"].InnerText);
                                settings.MaxHorizontalVelocity = float.Parse(node2["MaxHorizontal"].InnerText);
                                settings.MinVerticalVelocity = float.Parse(node2["MinVertical"].InnerText);
                                settings.MaxVerticalVelocity = float.Parse(node2["MaxVertical"].InnerText);
                                settings.EmitterVelocitySensitivity = float.Parse(node2["Sensitivity"].InnerText);
                                settings.EndVelocity = float.Parse(node2["Falloff"].InnerText);
                                settings.Gravity = ParseVector3(node2["Gravity"]);
                                break;
                            }
                        case "Color":
                            {
                                XmlElement c = node2["MinColor"];
                                XnaColor co = new XnaColor();
                                co.A = byte.Parse(c.Attributes["A"].Value);
                                co.R = byte.Parse(c.Attributes["R"].Value);
                                co.G = byte.Parse(c.Attributes["G"].Value);
                                co.B = byte.Parse(c.Attributes["B"].Value);
                                settings.MinColor = co;

                                c = node2["MaxColor"];
                                co.A = byte.Parse(c.Attributes["A"].Value);
                                co.R = byte.Parse(c.Attributes["R"].Value);
                                co.G = byte.Parse(c.Attributes["G"].Value);
                                co.B = byte.Parse(c.Attributes["B"].Value);
                                settings.MaxColor = co;
                                break;
                            }
                        case "Rotation":
                            {
                                settings.MinRotateSpeed = float.Parse(node2["MinRotateSpeed"].InnerText);
                                settings.MaxRotateSpeed = float.Parse(node2["MaxRotateSpeed"].InnerText);
                                break;
                            }
                        case "Size":
                            {
                                settings.MinStartSize = float.Parse(node2["MinStartSize"].InnerText);
                                settings.MaxStartSize = float.Parse(node2["MaxStartSize"].InnerText);
                                settings.MinEndSize = float.Parse(node2["MinEndSize"].InnerText);
                                settings.MaxEndSize = float.Parse(node2["MaxEndSize"].InnerText);
                                break;
                            }
                        case "Blend":
                            {
                                settings.AlphaSourceBlend = (Blend)(Enum.Parse(typeof(Blend), node2["AlphaSourceBlend"].InnerText));
                                settings.AlphaDestinationBlend = (Blend)(Enum.Parse(typeof(Blend), node2["AlphaDestinationBlend"].InnerText));
                                settings.AlphaBlendFunction = (BlendFunction)(Enum.Parse(typeof(BlendFunction), node2["AlphaBlendFunction"].InnerText));
                                //settings.BlendFactor = (XnaColor)(XnaColor.Parse(typeof(XnaColor), node2["BlendFactor"].InnerText));
                                settings.ColorBlendFunction = (BlendFunction)(Enum.Parse(typeof(BlendFunction), node2["ColorBlendFunction"].InnerText));
                                settings.ColorDestinationBlend = (Blend)(Enum.Parse(typeof(Blend), node2["ColorDestinationBlend"].InnerText));
                                settings.ColorSourceBlend = (Blend)(Enum.Parse(typeof(Blend), node2["ColorSourceBlend"].InnerText));
                                XmlElement c = node2["BlendFactor"];
                                XnaColor co = new XnaColor();
                                co.A = byte.Parse(c.Attributes["A"].Value);
                                co.R = byte.Parse(c.Attributes["R"].Value);
                                co.G = byte.Parse(c.Attributes["G"].Value);
                                co.B = byte.Parse(c.Attributes["B"].Value);
                                settings.BlendFactor = co;

                                break;
                            }
                    }
                }

                e.Add(settings);
            }
        }

        private static Vector3 ParseVector3(XmlElement node)
        {
            Vector3 v = new Vector3();

            v.X = float.Parse(node.Attributes["X"].Value);
            v.Y = float.Parse(node.Attributes["Y"].Value);
            v.Z = float.Parse(node.Attributes["Z"].Value);

            return v;
        }

        

        private static EmitterTypeSettings ParseEmitterTypeSettings(XmlElement node)
        {
            XmlElement type = (XmlElement)node.GetElementsByTagName("EmitterType")[0];
            EmitterType et = (EmitterType)Enum.Parse(typeof(EmitterType), type.InnerText);
            EmitterTypeSettings settings = new EmitterTypeSettings(et);
            switch (et)
            {
                case EmitterType.Circle:
                    {
                        CircleEmitterTypeSettings s = new CircleEmitterTypeSettings(0, false);
                        s.Radius = float.Parse(node["Radius"].InnerText);
                        s.RadiateOutward = bool.Parse(node["RadiateOutward"].InnerText);
                        s.StartAngle = float.Parse(node["StartAngle"].InnerText);
                        s.EndAngle = float.Parse(node["EndAngle"].InnerText);

                        settings = s;
                        break;
                    }
                case EmitterType.Line:
                    {
                        LineEmitterTypeSettings s = new LineEmitterTypeSettings(0, 0, false);
                        s.LineLength = float.Parse(node["LineLength"].InnerText);
                        s.PerpendicularVelocity = bool.Parse(node["PerpendicularVelocity"].InnerText);
                        s.Rotation = float.Parse(node["Rotation"].InnerText);
                        
                        #region OldWay
                        //foreach (XmlNode n in node.ChildNodes)
                        //{
                        //    if (n.Name == "LineLength")
                        //        s.LineLength = float.Parse(n.InnerText);
                        //    else if (n.Name == "PerpendicularVelocity")
                        //        s.PerpendicularVelocity = bool.Parse(n.InnerText);
                        //    else if (n.Name == "Rotation")
                        //        s.Rotation = float.Parse(n.InnerText);
                        //}
                        #endregion

                        settings = s;
                        break;
                    }
                case EmitterType.Point:
                    {
                        PointEmitterTypeSettings s = new PointEmitterTypeSettings();
                        XmlNode ellipticalFix = node["EllipticalVelocity"];
                        if (ellipticalFix != null)
                            s.EllipticalVelocity = bool.Parse(ellipticalFix.InnerText);
                        
                        settings = s;
                        break;
                    }
                case EmitterType.Rectangle:
                    {
                        RectangleEmitterTypeSettings s = new RectangleEmitterTypeSettings(new RectangleF(), 0, false);
                        RectangleF rec = new RectangleF();

                        XmlElement el = node["Rectangle"];
                        rec.X = float.Parse(el.Attributes["X"].Value);
                        rec.Y = float.Parse(el.Attributes["Y"].Value);
                        rec.Width = float.Parse(el.Attributes["Width"].Value);
                        rec.Height = float.Parse(el.Attributes["Height"].Value);

                        s.Rotation = float.Parse(node["Rotation"].InnerText);
                        s.RotateVelocity = bool.Parse(node["RotateVelocity"].InnerText);
                        s.CreateOnEdge = bool.Parse(node["CreateOnEdge"].InnerText);

                        #region Old Way
                        //foreach (XmlNode n in node.ChildNodes)
                        //{
                        //    if (n.Name == "Rectangle")
                        //    {
                        //        rec.X = float.Parse(n.Attributes["X"].Value);
                        //        rec.Y = float.Parse(n.Attributes["Y"].Value);
                        //        rec.Width = float.Parse(n.Attributes["Width"].Value);
                        //        rec.Height = float.Parse(n.Attributes["Height"].Value);
                        //    }
                        //    else if (n.Name == "Rotation")
                        //        s.Rotation = float.Parse(n.InnerText);
                        //    else if (n.Name == "RotateVelocity")
                        //        s.RotateVelocity = bool.Parse(n.InnerText);
                        //    else if (n.Name == "CreateOnEdge")
                        //        s.CreateOnEdge = bool.Parse(n.InnerText);
                        //}
                        #endregion

                        s.Rectangle = rec;
                        settings = s;
                        break;
                    }
            }

            return settings;

        }
        
    }
}
